package org.nico.cb.controller.article;

import java.util.List;

import org.nico.aoc.scan.annotations.Label;
import org.nico.cat.mvc.parameter.RequestMethod;
import org.nico.cat.mvc.scan.annotations.Body;
import org.nico.cat.mvc.scan.annotations.Lobby;
import org.nico.cat.mvc.scan.annotations.NotNull;
import org.nico.cat.mvc.scan.annotations.PathParam;
import org.nico.cat.mvc.scan.annotations.QueryParam;
import org.nico.cat.mvc.scan.annotations.RestCinema;
import org.nico.cat.mvc.scan.annotations.Verify;
import org.nico.cb.config.CdConfig;
import org.nico.cb.constant.MessageConstant;
import org.nico.cb.constant.ResponseCode;
import org.nico.cb.domain.Account;
import org.nico.cb.domain.article.Article;
import org.nico.cb.exception.AuthException;
import org.nico.cb.service.ArticleService;
import org.nico.cb.util.BaseUtils;
import org.nico.cb.util.CenteringUtils;
import org.nico.cb.vo.ResponseVo;
import org.nico.cb.vo.domain.ArticleVo;

@RestCinema
@Lobby(mapping = CdConfig.APP_AUTHC + "/article")
public class ArticleController {

	@Label
	private ArticleService articleService;
	
	@Lobby(requestMethod = RequestMethod.PUT)
	public ResponseVo put(
			@Body @Verify @NotNull ArticleVo articleVo
		) {
		ResponseVo result = new ResponseVo(); 
		try {
			Account account = BaseUtils.getCurrentAccount();
			articleVo.setId(CenteringUtils.productionID());
			articleVo.setAccountId(account.getId());
			articleService.insert(BaseUtils.copyObject(articleVo, Article.class));
			return result.setResponseCode(ResponseCode.CODE_SUCCESS).setData(articleVo);
		}catch(Exception e) {
			return result.setResponseCode(ResponseCode.CODE_ERROR).setData(null);
		}
	}
	
	@Lobby(requestMethod = RequestMethod.POST)
	public ResponseVo post(
			@Body @Verify @NotNull ArticleVo articleVo,
			@QueryParam @NotNull String id
		) {
		ResponseVo result = new ResponseVo(); 
		try {
			Account account = BaseUtils.getCurrentAccount();
			
			Article article = articleService.get(id);
			if(article == null) {
				return result.setResponseCode(ResponseCode.CODE_ENTITY_IS_NULL);
			}
			
			if(! account.getId().equals(article.getAccountId())) {
				throw new AuthException(MessageConstant.MESSAGE_AUTH_FAIL);
			}
			
			article.setTitle(articleVo.getTitle());
			article.setCoverUrl(articleVo.getCoverUrl());
			article.setDescription(articleVo.getContent().substring(0, 300));
			
			long row = articleService.update(article);
			
			if(row < 1) {
				return result.setResponseCode(ResponseCode.CODE_ERROR);
			}
			
			return result.setResponseCode(ResponseCode.CODE_SUCCESS).setData(article);
		}catch(Exception e) {
			return result.setResponseCode(ResponseCode.CODE_ERROR).setData(null);
		}
	}
	
	@Lobby(mapping = "/{id}", requestMethod = RequestMethod.DELETE)
	public ResponseVo delete(
			@PathParam @NotNull String id
		) {
		ResponseVo result = new ResponseVo(); 
		try {
			Account account = BaseUtils.getCurrentAccount();
			
			Article article = articleService.get(id);
			if(article == null) {
				return result.setResponseCode(ResponseCode.CODE_ENTITY_IS_NULL);
			}
			
			if(! account.getId().equals(article.getAccountId())) {
				throw new AuthException(MessageConstant.MESSAGE_AUTH_FAIL);
			}
			
			boolean deled = articleService.deleteById(id);
			
			if(! deled) {
				return result.setResponseCode(ResponseCode.CODE_ERROR);
			}
			
			return result.setResponseCode(ResponseCode.CODE_SUCCESS);
		}catch(Exception e) {
			return result.setResponseCode(ResponseCode.CODE_ERROR).setData(null);
		}
	}
	
	@Lobby(mapping = "/{id}", requestMethod = RequestMethod.GET)
	public ResponseVo get(
			@PathParam @NotNull String id
		) {
		ResponseVo result = new ResponseVo(); 
		try {
			Account account = BaseUtils.getCurrentAccount();
			Article entity = articleService.get(id);
			if(entity != null && account.getId().equals(entity.getAccountId())){
				return result.setResponseCode(ResponseCode.CODE_SUCCESS).setData(entity);
			}else{
				throw new AuthException(MessageConstant.MESSAGE_AUTH_FAIL);
			}
		}catch(Exception e) {
			return result.setResponseCode(ResponseCode.CODE_ERROR).setData(null);
		}
	}
	
	@Lobby(mapping = "/queries", requestMethod = RequestMethod.POST)
	public ResponseVo queries(
			@Body @NotNull ArticleVo articleVo
		) {
		ResponseVo result = new ResponseVo(); 
		try {
			Account account = BaseUtils.getCurrentAccount();
			articleVo.getQuery().put("accountId", account.getId());
			List<Article> datas = articleService.get(articleVo.getQuery(), articleVo.getPage());
			long count = articleService.count(articleVo.getQuery());
			return result.setResponseCode(ResponseCode.CODE_SUCCESS).setData(datas).setCount(count);
		}catch(Exception e) {
			return result.setResponseCode(ResponseCode.CODE_ERROR).setData(null);
		}
	}
	
}
